﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Linq;
using System.Net.NetworkInformation;
using Microsoft.Win32;


namespace SmallDHCPServer_C
{
    

    public partial class Form1 : Form
    {
        private clsDHCP cDhcp;
        private Button tt= new Button();

        private delegate void Adff();
      
        delegate void SimpleDelegate();
        public static string endIp, startIp, IndexIp, MacMask, AdapterIP;
        public bool NetCardAlive = false;
        private Thread dHCPThread = null;
      


        public Form1()
        {
            InitializeComponent();
            button4.Text = "Start DHCP Server";
            txtstart.Text = (string)Registry.LocalMachine.GetValue("IpAdd", "192.168.0.10");
            txtend.Text = (string)Registry.LocalMachine.GetValue("IpAdd", "192.168.0.20");
            //textBox2.Text = (string)Registry.LocalMachine.GetValue("MacMask", "00"); //add more data to this to block 
         }


        //tao pool va kiem tra pool

        public static bool Checkpool(string ipA)
        {
            long ipStart = BitConverter.ToInt32(IPAddress.Parse(startIp).GetAddressBytes().Reverse().ToArray(), 0);
            long ipEnd = BitConverter.ToInt32(IPAddress.Parse(endIp).GetAddressBytes().Reverse().ToArray(), 0);
            long ip = BitConverter.ToInt32(IPAddress.Parse(ipA).GetAddressBytes().Reverse().ToArray(), 0);
            return ip >= ipStart && ip <= ipEnd;
        }


        public static bool CheckAlive(string IpAdd)
        {
            Ping pingSender = new Ping();
            IPAddress address;
            PingReply reply;


            try
            {
                 address = IPAddress.Parse(IpAdd);
                 reply = pingSender.Send(address,100);
                 if (reply.Status == IPStatus.Success)
                 {
                     Console.WriteLine("Address: {0}", reply.Address.ToString());
                     Console.WriteLine("RoundTrip time: {0}", reply.RoundtripTime);
                     Console.WriteLine("Time to live: {0}", reply.Options.Ttl);
                     Console.WriteLine("Don't fragment: {0}", reply.Options.DontFragment);
                     Console.WriteLine("Buffer size: {0}", reply.Buffer.Length);
                     return true;
                 }
                 else
                 {
                     Console.WriteLine(reply.Status);
                     return false;
                 }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            finally
            {
                if (pingSender != null)  pingSender.Dispose();
                pingSender = null;
                address = null;
                reply = null;
            }
         }

     


        private static uint IPAddressToLongBackwards(string IPAddr)
        {
            System.Net.IPAddress oIP = System.Net.IPAddress.Parse(IPAddr);//chuyen mot string dia chi ip sang doi tuong System.Net.IPAddress
            byte[] byteIP = oIP.GetAddressBytes();//chuyen doi doi tuong ipaddress sang mot mang cac bytes


            uint ip = (uint)byteIP[0] << 24;
            ip += (uint)byteIP[1] << 16;
            ip += (uint)byteIP[2] << 8;
            ip += (uint)byteIP[3];

            return ip;
        }

        //chuyen doi tu ip dang byte sang lai dang chuoi ip
        private string GetIPAdd()
        {
            IPAddress ipadd;
            byte[] yy;
            UInt32 iit;
            try
            {
                iit = IPAddressToLongBackwards(IndexIp);
                iit -= 1;
                    do
                    {
                        iit += 1;
                        yy = new byte[4];
                        yy[3] = (byte)(iit);
                        yy[2] = (byte)(iit >> 8);
                        yy[1] = (byte)(iit >> 16);
                        yy[0] = (byte)(iit >> 24);
                        ipadd = new IPAddress(yy);//truyền tham số là mảng byte số nguyen.
                    }
                    while (CheckAlive(ipadd.ToString()) == true);
                    //kiem tat ca cac ip dang khong su dung
                 
                return ipadd.ToString();
            }
            catch 
            {
                return null;
            }
        }

        public void cDhcp_Announced(cDHCPStruct d_DHCP, string MacId)
        {
            string str = string.Empty;
            string temp = string.Empty;
            if (MacId.StartsWith(MacMask) == true) //kiểm tra xem mask phù hợp không
            {
                //Một số các thông số mặc định + test
                d_DHCP.dData.IPAddr = GetIPAdd();
                d_DHCP.dData.SubMask = "255.255.255.0";
                d_DHCP.dData.LeaseTime = 2000;
                d_DHCP.dData.ServerName = "DHCP server";
                d_DHCP.dData.MyIP = AdapterIP;
                d_DHCP.dData.RouterIP = "192.168.0.1";
                d_DHCP.dData.LogServerIP = "0.0.0.0";
                d_DHCP.dData.DomainIP = "0.0.0.0";
                if (Checkpool(d_DHCP.dData.IPAddr))
                {
                    str = "IP duoc yeu cau cho may co dia chi mac: " + MacId;
                    cDhcp.SendDHCPMessage(DHCPMsgType.DHCPOFFER, d_DHCP);//broadcast goi tin offer;
                }
                else
                {
                    str = "khong con ip de cap";
                }
            }
            else
            {
                str = "Mac: " + MacId + " khong thuoc mask";
            }
          
            SimpleDelegate lst = delegate
            {
                listBox1.Items.Add(str);
            };
            Invoke(lst);
        //Application.DoEvents()
        }

        public void cDhcp_Request(cDHCPStruct d_DHCP, string MacId)
        {
            string str = string.Empty;
            if (MacId.StartsWith(MacMask) == true)
            {
                //gửi off
                d_DHCP.dData.IPAddr = GetIPAdd(); 
                d_DHCP.dData.SubMask = "255.255.255.0";
                d_DHCP.dData.LeaseTime = 2000; 
                d_DHCP.dData.ServerName = "DHCP Server";
                d_DHCP.dData.MyIP = AdapterIP;
                d_DHCP.dData.RouterIP = "192.168.0.1";
                d_DHCP.dData.LogServerIP = "0.0.0.0";
                d_DHCP.dData.DomainIP = "0.0.0.0";
                if (Checkpool(d_DHCP.dData.IPAddr))
                {
                    cDhcp.SendDHCPMessage(DHCPMsgType.DHCPACK, d_DHCP);//broadcast goi tin dhcpack
                    str = "IP " + d_DHCP.dData.IPAddr + " duoc gan cho may co dia chi mac: " + MacId;
                }
                else
                {
                    str = "khong con IP de cap";
                }
            }
            else 
            {
                str = "Mac: " + MacId + " khong thuoc mask!";
            }
            SimpleDelegate lst = delegate
            {
                listBox1.Items.Add(str);
            };

            Invoke(lst);
            
        }

        public void oou()
        {
            Console.WriteLine("LL");
        }


         private void button4_Click(object sender, EventArgs e)
        {
            switch (button4.Text)
            {
                case "Start DHCP Server":

                    AdapterIP = "0.0.0.0"; //cho phep du lieu tu tat ca cac card mang
                    button4.Text = "Stop DHCP Server";
                    cDhcp = new clsDHCP(AdapterIP);
                    cDhcp.Announced += new clsDHCP.AnnouncedEventHandler(cDhcp_Announced);
                    cDhcp.Request += new clsDHCP.RequestEventHandler(cDhcp_Request);
                    startIp = txtstart.Text;
                    endIp = txtend.Text;
                    IndexIp = startIp;
                    MacMask = "00";
                    dHCPThread = new Thread(cDhcp.StartDHCPServer);
                    dHCPThread.Start();
                    break;
                default:
                    button4.Text = "Start DHCP Server";
                    cDhcp.Dispose();

                    break;
            }
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
          
            Application.DoEvents();
            button4.PerformClick();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            cDhcp.Dispose();
        }
   }
}